/** @format */

import { connect, ConsumeMessage } from 'amqplib';

const recordTaskQueue = 'recordTask';

const recordNotiQueue = `recordNoti[${Date.now()}]`;
// const recordNotiQueue = `fdgsdfgsdfg`;
const recordNotiExchange = 'notifacation';
const recordNotiExchangeType = 'fanout';
const recordNotiRoutingKey = '';

async function bootstrap(): Promise<void> {
    const amqp = await connect('amqp://gj:123qwe@10.0.0.215:5672');

    const chTask = await amqp.createChannel();
    // 为方式RabbitMQ退出或者崩溃时重启后丢失队列信息，这里配置durable:true（同时在消费者脚本中也要定义durable:true）
    chTask.assertQueue(recordTaskQueue, { durable: false }); //Assert Queue
    // Set the prefetch count for this channel. The count given is the maximum number of messages sent over the channel that can be awaiting acknowledgement; once there are count messages outstanding, the server will not send more messages on this channel until one or more have been acknowledged. A falsey value for count indicates no such limit.
    // 设置此通道的预取计数。给定的计数是通过通道可以等待确认的最大消息数；一旦有待处理的消息计数，服务器将不会在该通道上发送更多消息，除非已确认一个或多个消息。计数的假值表示没有这种限制。
    chTask.prefetch(5);
    chTask.consume(
        recordTaskQueue,
        (msg: ConsumeMessage | null) => {
            if (msg) {
                console.log(`${msg.content.toString()} => [${Date.now()}]`);
                setTimeout(() => {
                    chTask.ack(msg);
                }, 5000);
            }
        },
        {
            // noAck配置（默认为false）表明consumer是否需要在处理完后反馈ack给producer，
            // 如果设置为true，则RabbitMQ服务如果将任务send至此consumer后不关心任务实际处理结果，send任务后直接标记已完成；
            // 否则，RabbiMQ得到ack反馈后才标记为已完成，如果一直未收到ack默认会一直等待ack然后标记，另外如果接收到nack或者该consumer进程退出则继续dispatcher任务
            noAck: false,
        },
    );

    const chNoti = await amqp.createChannel();
    chNoti.assertExchange(recordNotiExchange, recordNotiExchangeType, { durable: false });
    // if true, scopes the queue to the connection (defaults to false)
    // 如果为true，则将队列的作用域限定为连接（默认为false）
    // { exclusive: true } RabbitMQ允许你将一个Queue声明成为排他性的（Exclusive Queue）
    chNoti.assertQueue(recordNotiQueue, { exclusive: true, autoDelete: true });
    chNoti.bindQueue(recordNotiQueue, recordNotiExchange, '');
    chNoti.consume(
        recordNotiQueue,
        (msg: ConsumeMessage | null) => {
            if (msg) {
                console.log(`${msg.content.toString()} => [${Date.now()}]`);
            }
        },
        { noAck: true },
    );
}
bootstrap();
